package org.light.jpa.verb;

import java.util.ArrayList;
import java.util.List;

import org.light.core.Writeable;
import org.light.domain.Domain;
import org.light.domain.JavascriptBlock;
import org.light.domain.JavascriptMethod;
import org.light.domain.Method;
import org.light.domain.Signature;
import org.light.domain.Statement;
import org.light.domain.StatementList;
import org.light.domain.Type;
import org.light.easyui.EasyUIPositions;
import org.light.exception.ValidateException;
import org.light.jpa.core.JpqlReflector;
import org.light.utils.MybatisSqlReflector;
import org.light.utils.StringUtil;
import org.light.utils.WriteableUtil;

public class Revoke extends org.light.complexverb.Revoke{

	@Override
	public Method generateDaoImplMethod() throws Exception {
		return null;
	}

	@Override
	public Method generateDaoMethodDefinition() throws Exception {
		Method method = new Method();
		if (StringUtil.isBlank(this.slave.getAlias())){
			method.setStandardName("revoke"+this.slave.getCapFirstDomainName()+"From"+this.master.getCapFirstDomainName());
		} else {
			method.setStandardName("revoke"+StringUtil.capFirst(this.slave.getAlias())+"From"+this.master.getCapFirstDomainName());
		}
		method.setReturnType(new Type("Integer"));
		method.setThrowException(true);
		method.addSignature(new Signature(1, StringUtil.lowerFirst(this.master.getStandardName())+"Id", this.master.getDomainId().getClassType()));
		if (StringUtil.isBlank(this.slave.getAlias())){
			method.addSignature(new Signature(2, StringUtil.lowerFirst(this.slave.getStandardName())+"Id", this.slave.getDomainId().getClassType()));
		} else {
			method.addSignature(new Signature(2, StringUtil.lowerFirst(this.slave.getAlias())+"Id", this.slave.getDomainId().getClassType()));
		}
		
		method.addMetaData("Transactional");
		method.addMetaData("Modifying");
		method.addMetaData("Query(value=\""+JpqlReflector.generateDeleteLinkTwoSql(master,slave)+"\", nativeQuery=true)");

		return method;
	}

	@Override
	public Method generateServiceMethodDefinition() throws Exception {
		Method method = new Method();
		method.setStandardName(StringUtil.lowerFirst(getVerbName()));
		method.setReturnType(new Type("Boolean"));
		method.setThrowException(true);
		method.addSignature(new Signature(1, StringUtil.lowerFirst(this.master.getStandardName())+"Id", this.master.getDomainId().getClassType()));
		if (StringUtil.isBlank(this.slave.getAlias())){
			method.addSignature(new Signature(2, StringUtil.lowerFirst(this.slave.getStandardName())+"Ids", new Type("String")));
		} else {
			method.addSignature(new Signature(2, StringUtil.lowerFirst(this.slave.getAlias())+"Ids", new Type("String")));
		}
		return method;
	}

	@Override
	public Method generateServiceImplMethod() throws Exception {
		Method method = new Method();
		method.setStandardName(StringUtil.lowerFirst(getVerbName()));
		method.setReturnType(new Type("Boolean"));
		method.setThrowException(true);
		method.addAdditionalImport("java.util.List");
		if (!"datadummy".equalsIgnoreCase(this.master.getSchema())) {
			method.addAdditionalImport("org.springframework.transaction.annotation.Transactional");
		}
		method.addAdditionalImport(this.master.getPackageToken()+"."+this.master.getDaoSuffix()+"."+this.master.getStandardName()+"Dao");
		method.addAdditionalImport(this.slave.getPackageToken()+"."+this.slave.getServiceSuffix()+"."+this.slave.getStandardName()+"Service");
		method.addSignature(new Signature(1, StringUtil.lowerFirst(this.master.getStandardName())+"Id", this.master.getDomainId().getClassType()));
		if (StringUtil.isBlank(this.slave.getAlias())){
			method.addSignature(new Signature(2, StringUtil.lowerFirst(this.slave.getStandardName())+"Ids", new Type("String")));
		} else {
			method.addSignature(new Signature(2, StringUtil.lowerFirst(this.slave.getAlias())+"Ids", new Type("String")));
		}
		method.addMetaData("Override");	
		if (!"datadummy".equalsIgnoreCase(this.master.getSchema())) {
			method.addMetaData("Transactional");	
		}
		
		List<Writeable> list = new ArrayList<Writeable>();
		if (StringUtil.isBlank(this.slave.getAlias())){
			list.add(new Statement(1000L,2,"String [] "+this.slave.getLowerFirstDomainName()+"IdsArr = "+this.slave.getLowerFirstDomainName()+"Ids.split(\",\");"));
			list.add(new Statement(2000L,2,"for (int i = 0; i < "+this.slave.getLowerFirstDomainName()+"IdsArr.length; i++ ){"));
			if (this.slave.getDomainId().getClassType().toString().equals("String")) list.add(new Statement(3000L,2,"String "+this.slave.getLowerFirstDomainName()+"Id = "+this.slave.getLowerFirstDomainName()+"IdsArr[i];"));
			if (this.slave.getDomainId().getClassType().toString().equals("Long")) list.add(new Statement(3000L,2,"Long "+this.slave.getLowerFirstDomainName()+"Id = Long.parseLong("+this.slave.getLowerFirstDomainName()+"IdsArr[i]);"));
			if (this.slave.getDomainId().getClassType().toString().equals("Integer")) list.add(new Statement(3000L,2,"Integer "+this.slave.getLowerFirstDomainName()+"Id = Integer.parseInt("+this.slave.getLowerFirstDomainName()+"IdsArr[i]);"));
			if (this.master instanceof org.light.domain.Enum && !"datadummy".equalsIgnoreCase(this.master.getSchema())) {
				list.add(new Statement(4000L,2,"Integer success = mtmDao."+generateDaoMethodDefinition().generateStandardCallString()+";"));
			} else {
				list.add(new Statement(4000L,2,"Integer success = dao."+generateDaoMethodDefinition().generateStandardCallString()+";"));
			}
			list.add(new Statement(5000L,2,"if (success < 0) return false;"));
			list.add(new Statement(6000L,2,"}"));
			list.add(new Statement(7000L,2,"return true;"));
		} else {
			list.add(new Statement(1000L,2,"String [] "+StringUtil.lowerFirst(this.slave.getAlias())+"IdsArr = "+StringUtil.lowerFirst(this.slave.getAlias())+"Ids.split(\",\");"));
			list.add(new Statement(2000L,2,"for (int i = 0; i < "+StringUtil.lowerFirst(this.slave.getAlias())+"IdsArr.length; i++ ){"));
			if (this.slave.getDomainId().getClassType().toString().equals("String")) list.add(new Statement(3000L,2,"String "+StringUtil.lowerFirst(this.slave.getAlias())+"Id = "+StringUtil.lowerFirst(this.slave.getAlias())+"IdsArr[i];"));
			if (this.slave.getDomainId().getClassType().toString().equals("Long")) list.add(new Statement(3000L,2,"Long "+StringUtil.lowerFirst(this.slave.getAlias())+"Id = Long.parseLong("+StringUtil.lowerFirst(this.slave.getAlias())+"IdsArr[i]);"));
			if (this.slave.getDomainId().getClassType().toString().equals("Integer")) list.add(new Statement(3000L,2,"Integer "+StringUtil.lowerFirst(this.slave.getAlias())+"Id = Integer.parseInt("+StringUtil.lowerFirst(this.slave.getAlias())+"IdsArr[i]);"));
			if (this.master instanceof org.light.domain.Enum && !"datadummy".equalsIgnoreCase(this.master.getSchema())) {
				list.add(new Statement(4000L,2,"Integer success = mtmDao."+generateDaoMethodDefinition().generateStandardCallString()+";"));
			} else {
				list.add(new Statement(4000L,2,"Integer success = dao."+generateDaoMethodDefinition().generateStandardCallString()+";"));
			}
			list.add(new Statement(5000L,2,"if (success < 0) return false;"));
			list.add(new Statement(6000L,2,"}"));
			list.add(new Statement(7000L,2,"return true;"));
		}
		method.setMethodStatementList(WriteableUtil.merge(list));
		return method;
	}

	public Revoke(Domain master,Domain slave) throws ValidateException{
		super(master,slave);
	}	
}
